using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace ReportMaintenanceUtility
{
	public class ParameterValue : GenericBase<ParameterValue>
	{
		#region PRIVATE MEMBERT(S)

		private string				_label		= string.Empty;
		private string				_value		= string.Empty;
		private ParameterValueType	_seed	= null;

		#endregion


		#region PUBLIC PROPERTIES

		public string Label
		{
			get { return this._label; }
			set
			{
				this.PrepStateChange("Label");
				this._label = value;
			}
		}
		public string Value
		{
			get { return this._value; }
			set
			{
				this.PrepStateChange("Value");
				this._value = value;
			}
		}

		#endregion


		#region CONSTRUCTOR(S)

		private ParameterValue(ParameterValue pv)
		{
			if (pv == null)
			{
				throw new ArgumentNullException();
			}
			else
			{
				this._seed = (ParameterValueType)pv.CreateSeedCopy();
				base.CopyListeners(pv);
				this.Initialize();
			}
		}

		public ParameterValue(ParameterValueType pvt)
		{
			if (pvt == null)
			{
				throw new ArgumentNullException();
			}
			else
			{
				this._seed = pvt;
				this.Initialize();
			}
		}

		protected override void Initialize()
		{
			for (int i = 0; i < this._seed.ItemsElementName.Length; i++)
			{
				switch (this._seed.ItemsElementName[i])
				{
					case ItemsChoiceType32.Label:
						this._label = this._seed.Items[i].ToString();
						break;
					case ItemsChoiceType32.Value:
						this._value = this._seed.Items[i].ToString();
						break;
				}
			}
		}

		#endregion


		#region	INTERFACE IMPLEMENTATION(S)

		public override bool EqualTo(ParameterValue other)
		{
			if (other == null)
			{
				return false;
			}
			else
			{
				return (this._label == other.Label && this._value == other.Value);
			}
		}

		public override List<ChangeLog> SaveState()
		{
			List<ChangeLog> log = new List<ChangeLog>();

			if (this._isDirty)
			{
				int idx = -1;
				List<ItemsChoiceType32> elements = new List<ItemsChoiceType32>(this._seed.ItemsElementName);

				if (this._label != this._copy._label)
				{
					idx = elements.IndexOf(ItemsChoiceType32.Label);
					if (string.IsNullOrEmpty(this._label) && idx > -1)
					{
						this.RemoveSeedItem(elements, idx);
					}
					else
					{
						if (idx == -1)
						{
							this.AddSeedItem(elements, ItemsChoiceType32.Label, this._label);
						}
						else
						{
							this._seed.Items[idx] = this._label;
						}
					}
				}

				if (this._value != this._copy._value)
				{
					idx = elements.IndexOf(ItemsChoiceType32.Value);
					if (string.IsNullOrEmpty(this._value) && idx > -1)
					{
						this.RemoveSeedItem(elements, idx);
					}
					else
					{
						if (idx == -1)
						{
							this.AddSeedItem(elements, ItemsChoiceType32.Value, this._value);
						}
						else
						{
							this._seed.Items[idx] = this._value;
						}
					}
				}
			}

			this.ClearState();
			return log;
		}

		public override void RestoreState()
		{
			if (this._copy != null)
			{
				this._label = this._copy._label;
				this._value = this._copy._value;
			}
			this.ClearState();
		}

		public override ParameterValue CreateDeepCopy()
		{
			if (this._copy != null)
			{
				return this._copy;
			}
			return new ParameterValue(this);
		}

		public override object CreateSeedCopy()
		{
			ParameterValueType pvt = new ParameterValueType();
			List<ItemsChoiceType32> elements = new List<ItemsChoiceType32>(this._seed.ItemsElementName);
			List<object> items = new List<object>(this._seed.Items);

			pvt.ItemsElementName = elements.ToArray();
			pvt.Items = items.ToArray();

			return pvt;
		}

		public ParameterValueType GetSeedObject()
		{
			return this._seed;
		}

		private void RemoveSeedItem(List<ItemsChoiceType32> elements, int idx)
		{
			if (idx > -1 && idx < elements.Count)
			{
				elements.RemoveAt(idx);

				List<object> items = new List<object>(this._seed.Items);
				items.RemoveAt(idx);

				this._seed.Items = items.ToArray();
				this._seed.ItemsElementName = elements.ToArray();
			}
		}

		private void AddSeedItem(List<ItemsChoiceType32> elements, ItemsChoiceType32 element, object value)
		{
			if (!elements.Contains(element))
			{
				elements.Add(element);

				List<object> items = new List<object>(this._seed.Items);
				items.Add(value);

				this._seed.ItemsElementName = elements.ToArray();
				this._seed.Items = items.ToArray();
			}
		}

		#endregion
	}
}